package com.winchain.chainbill.risk.biz.access.cmd;

import com.shell.bee.acct.transaction.po.AcctTxRec;
import com.shell.bee.base.utils.DateUtil;
import com.shell.bee.base.utils.StringUtil;
import com.shell.bee.base.utils.SystemUtil;
import com.shell.framework.command.CallbackContext;
import com.shell.framework.command.CommandContext;
import com.shell.framework.command.ICallback;
import com.shell.framework.command.ICommand;
import com.shell.framework.utils.CommonDataUtil;
import com.winchain.chainbill.ChainBillUtil;
import com.winchain.chainbill.basic.StateChangedException;
import com.winchain.chainbill.basic.context.TimeoutOperation;
import com.winchain.chainbill.receivables.base.po.ArOperation;
import com.winchain.chainbill.receivables.base.po.ArRecord;
import com.winchain.chainbill.receivables.base.service.ArOptService;
import com.winchain.chainbill.receivables.base.service.ArRecordService;
import com.winchain.chainbill.risk.base.po.RmAccessQuota;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class AccessMoveCmd implements ICommand<RmAccessQuota>, ICallback<RmAccessQuota, AcctTxRec> {
	protected final Log logger = LogFactory.getLog(getClass());
	@Autowired
	private ArRecordService arRecordService;
	@Autowired
	private ArOptService arOptService;

	public boolean execute(CommandContext<RmAccessQuota> context) throws Exception {
		RmAccessQuota rmAccessQuota = (RmAccessQuota) context.getSource();

		ArOperation opt = (ArOperation) context.getValue("Operation");

		String bizId = rmAccessQuota.getAccId();
		String state = opt.getState();
		String optCode = opt.getOptCode();
		String nextState = opt.getNextState();
		String limitDate = opt.getLimitDate();
		String remark = opt.getRemark();
		int optSeq = rmAccessQuota.getOptSeq().intValue();
		Boolean noTimeout = opt.getNoTimeout();
		String timeoutOptCode;
		if ((noTimeout == null) || (!noTimeout.booleanValue())) {
			TimeoutOperation timeoutOpt = (TimeoutOperation) context.getValue("TimeoutOperation");
			timeoutOptCode = "B2";
			String timeoutState = "";
			String timeoutRemark = "����������������������";
			if (timeoutOpt != null) {
				timeoutOptCode = timeoutOpt.getOptCode();
				timeoutState = timeoutOpt.getState();
				timeoutRemark = timeoutOpt.getRemark();
			}
			boolean timeout = false;
			String lastLimitDate = null;
			if (optSeq != 0) {
				ArOperation lastOpt = this.arOptService.getByBizIdAndSeqNo(rmAccessQuota.getAccId(), optSeq);
				lastLimitDate = lastOpt.getLimitDate();
			}
			if (StringUtil.notEmpty(lastLimitDate)) {
				timeout = ChainBillUtil.isTimeout(lastLimitDate);
			}
			context.setValue("Timeout", Boolean.valueOf(timeout));
			if (timeout) {
				optCode = timeoutOptCode;
				nextState = timeoutState;
				remark = timeoutRemark;
				limitDate = "";
			} else {
				RmAccessQuota newrmAccessQuota = (RmAccessQuota) context.getValue("NewrmAccessQuota");
				if (newrmAccessQuota != null) {
					BeanUtils.copyProperties(newrmAccessQuota, rmAccessQuota);
				}
			}
		}
		rmAccessQuota.setOptSeq(Integer.valueOf(++optSeq));
		List<ArRecord> records = this.arRecordService.selectRecordByAccId(bizId);
		for (ArRecord arRecoid : records) {
			arRecoid.setCurArState(arRecoid.getArState());
			if ("RB".equals(optCode)) {
				nextState = arRecoid.getArStateMod();
			}
			arRecoid.setArState(nextState);
			int affectedRows = this.arRecordService.updateRecordOptimistically(arRecoid);
			if (affectedRows != 1) {
				this.logger.error("arId =" + bizId + "������������������������");
				throw new StateChangedException("��������" + arRecoid.getArNo() + "��������������������������������");
			}
		}
		opt.setOptId(SystemUtil.getUUID());
		opt.setBizId(bizId);
		opt.setState(state);
		opt.setOptCode(optCode);
		opt.setNextState(nextState);
		opt.setLimitDate(limitDate);
		opt.setRemark(remark);
		opt.setOptTime(DateUtil.getSystemDateTime());
		opt.setOprId(CommonDataUtil.getUserId());
		opt.setSeqNo(Integer.valueOf(optSeq));
		this.arOptService.save(opt);

		return false;
	}

	public boolean callback(CallbackContext<RmAccessQuota, AcctTxRec> context) throws Exception {
		execute(context);

		return false;
	}
}
